import { LatLng, toLatLng } from "./LatLng";

export class LatLngBounds {
  _southWest; // 西南
  _northEast; // 东北
  //  (LatLng, LatLng) or (LatLng[])
  constructor(corner1, corner2) {
    if (!corner1) {
      return;
    }

    const latlngs = corner2 ? [corner1, corner2] : corner1;

    for (let i = 0, len = latlngs.length; i < len; i++) {
      this.extend(latlngs[i]);
    }
  }

  extend(obj) {
    const sw = this._southWest,
      ne = this._northEast;
    let sw2, ne2;
    if (obj instanceof LatLng) {
      sw2 = obj;
      ne2 = obj;
    } else if (obj instanceof LatLngBounds) {
      sw2 = obj._southWest;
      ne2 = obj._northEast;

      if (!sw2 || !ne2) {
        return this;
      }
    } else {
      return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this;
    }

    if (!sw && !ne) {
      this._southWest = new LatLng(sw2.lng, sw2.lat);
      this._northEast = new LatLng(ne2.lng, ne2.lat);
    } else {
      sw.lat = Math.min(sw2.lat, sw.lat);
      sw.lng = Math.min(sw2.lng, sw.lng);
      ne.lat = Math.max(ne2.lat, ne.lat);
      ne.lng = Math.max(ne2.lng, ne.lng);
    }

    return this;
  }

  getCenter() {
    return new LatLng(
      (this._southWest.lat + this._northEast.lat) / 2,
      (this._southWest.lng + this._northEast.lng) / 2
    );
  }

  getSouthWest() {
    return this._southWest;
  }

  // @method getNorthEast(): LatLng
  // Returns the north-east point of the bounds.
  getNorthEast() {
    return this._northEast;
  }

  // @method getNorthWest(): LatLng
  // Returns the north-west point of the bounds.
  getNorthWest() {
    return new LatLng(this.getNorth(), this.getWest());
  }

  // @method getSouthEast(): LatLng
  // Returns the south-east point of the bounds.
  getSouthEast() {
    return new LatLng(this.getSouth(), this.getEast());
  }

  // @method getWest(): Number
  // Returns the west longitude of the bounds
  getWest() {
    return this._southWest.lng;
  }

  // @method getSouth(): Number
  // Returns the south latitude of the bounds
  getSouth() {
    return this._southWest.lat;
  }

  // @method getEast(): Number
  // Returns the east longitude of the bounds
  getEast() {
    return this._northEast.lng;
  }

  // @method getNorth(): Number
  // Returns the north latitude of the bounds
  getNorth() {
    return this._northEast.lat;
  }
}

export function toLatLngBounds(a, b) {
  if (a instanceof LatLngBounds) {
    return a;
  }
  return new LatLngBounds(a, b);
}
